//
//  NetworkTool.m
//  XHH_networkTool
//
//  Created by xiaohuihui on 2016/11/26.
//  Copyright © 2016年 30-陈辉华. All rights reserved.
//

#import "NetworkTool.h"
#import <MBProgressHUD.h>
#import "UIView+LZCView.h"
#import "LoginViewController.h"
#import "WebViewController.h"
#import "AddJobViewController.h"
#import "AddResumeViewController.h"
#import "LoginPhoneViewController.h"
#import "HomeViewController.h"

@implementation NetworkTool {
    UIViewController *_currVC;
}

+ (instancetype)sharedTool {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] initWithBaseURL:nil];
    });
    return instance;
}
- (instancetype)initWithBaseURL:(NSURL *)url
{
	if (self = [super initWithBaseURL:url]) {
		self.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
	}
	return self;

}

- (void)requestWithName:(NSString *)name
              URLString:(NSString *)URLString
             parameters:(id)parameters
                 method:(NSString *)method
               callBack:(void(^)(id responseObject))callBack {
    
    // 考虑错误返回，回调处理
    
//    _currVC = [((AppDelegate *)[UIApplication sharedApplication].delegate) topViewController];
    _currVC = [[[UIView alloc] init] topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
    
    NSArray *nameArr = @[@"获取关注", @"获取粉丝", @"用户搜索", @"获取游客token", @"刷新用户token", @"获取广告", @"获取用户信息", @"发送礼物", @"加入购物车", @"获取动态", @"移出购物车", @"获取评论", @"获取在线专家", @"获取问题列表", @"获取动态", @"获取历史直播", @"获取科普列表", @"获取视频列表", @"获取直播", @"未读消息", @"获取岗位/人才信息", @"获取商品", @"获取用户信息", @"获取岗位/人才信息", @"获取商城首页商品",@"获取首页按钮图片&标题", @"批量查询用户信息", @"删除直播"];
    
    // 以上几个&包含以下的不出现hud
    if (![nameArr containsObject:name] &&
		![name containsString:@"投递箱"]&&
		![name containsString:@"列表"]&&
		![name containsString:@"面试管理"]&&
		![name containsString:@"订单"]) {
		if (_currVC.view != nil) {
			MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:_currVC.view animated:YES];
			[UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]].color = [UIColor whiteColor];
			hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
			hud.bezelView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
		}
    }
    
    
    NSMutableDictionary *mDict = [[NSMutableDictionary alloc] initWithDictionary:parameters];
    [mDict setObject:[self jwtDate:0] forKey:@"iat"];
    [mDict setObject:[self jwtDate:60] forKey:@"exp"];
    
   // NSLog(@"%@ 参数 = %@", name, mDict);
    
//    NSLog(@"%@", [GetUserDefaule(Token) valueForKey:@"access_token"]);
//    if ([GetUserDefaule(Token) valueForKey:@"access_token"] == NULL) {
//        NSLog(@"wu");
//        sleep(1);
//    }
//    else
//        NSLog(@"xxxxx");
    
    // 请求头
    [self.requestSerializer setValue:[GetUserDefaule(Token) valueForKey:@"access_token"] forHTTPHeaderField:@"Authorization"];
//    NSLog(@"--------token = %@", GetUserDefaule(Token));
    // 移除请求回来的responseObjective的空类型（针对性使用）
    AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
    response.removesKeysWithNullValues = YES;
    self.responseSerializer = response;
    
    // JWT秘钥
    NSString *secret = JWTSecret;
    id<JWTAlgorithm> algorithm = [JWTAlgorithmFactory algorithmByName:@"HS256"];
    JWTBuilder *jwtBuilder = [JWTBuilder encodePayload:mDict].secret(secret).algorithm(algorithm);
    NSString *jwtStr = [NSString stringWithFormat:@"%@", jwtBuilder.encode];
    
//    NSLog(@"jwt = %@", jwtStr);
    
    
    // path ，body ， query 无论哪种都加上“jwt=%@”
    
    if ([method isEqualToString:@"GET"]) {
        NSString *url = [NSString stringWithFormat:@"%@?jwt=%@", URLString, jwtStr];
        [self GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            id obj = [self netSuccess:responseObject];
            NSLog(@"%@ success = %@", name, obj);
            callBack(obj);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
			NSLog(@"报错的接口是%@", URLString);
            [self netFailure:error];
        }];
    }
    
    
    else if ([method isEqualToString:@"POST"]) {
        [self POST:URLString parameters:@{@"jwt":jwtStr} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            id obj = [self netSuccess:responseObject];
            NSLog(@"%@ success = %@", name, obj);
            callBack(obj);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@", error);
			NSLog(@"报错的接口是%@", URLString);
            [self netFailure:error];
        }];
    }
    
    else if ([method isEqualToString:@"PUT"]) {
        [self PUT:URLString parameters:@{@"jwt":jwtStr} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            id obj = [self netSuccess:responseObject];
            NSLog(@"%@ success = %@", name, obj);
            callBack(obj);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@", error);
			NSLog(@"报错的接口是%@", URLString);
            [self netFailure:error];
        }];
    }
    
    else if ([method isEqualToString:@"DELETE"]) {
        [self DELETE:URLString parameters:@{@"jwt":jwtStr} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            id obj = [self netSuccess:responseObject];
            NSLog(@"%@ success = %@", name, obj);
            callBack(obj);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
			NSLog(@"报错的接口是%@", URLString);
            [self netFailure:error];
        }];
    }
    
}

/**新增一个封装包含有错误的回调的*/
- (void)requestWithName:(NSString *)name
			  URLString:(NSString *)URLString
			 parameters:(id)parameters
				 method:(NSString *)method
			   callBack:(void(^)(id responseObject))callBack
			   failCallBack:(void(^)(id responseObject))failCallBack {
	
	// 考虑错误返回，回调处理
	
	//    _currVC = [((AppDelegate *)[UIApplication sharedApplication].delegate) topViewController];
	_currVC = [[[UIView alloc] init] topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
	
	NSArray *nameArr = @[@"获取关注", @"获取粉丝", @"用户搜索", @"获取游客token", @"刷新用户token", @"获取广告", @"获取用户信息", @"发送礼物", @"加入购物车", @"获取动态", @"移出购物车", @"获取评论", @"获取在线专家", @"获取问题列表", @"获取动态", @"获取历史直播", @"获取科普列表", @"获取视频列表", @"获取直播", @"未读消息", @"获取岗位/人才信息", @"获取商品", @"获取用户信息", @"获取岗位/人才信息", @"获取商城首页商品",@"获取首页按钮图片&标题", @"批量查询用户信息"];
	
	// 以上几个&包含以下的不出现hud
	if (![nameArr containsObject:name] &&
		![name containsString:@"投递箱"]&&
		![name containsString:@"列表"]&&
		![name containsString:@"面试管理"]&&
		![name containsString:@"订单"]) {
		if (_currVC.view != nil) {
			[MBProgressHUD showHUDAddedTo:_currVC.view animated:YES];
		}
	}
	
	
	NSMutableDictionary *mDict = [[NSMutableDictionary alloc] initWithDictionary:parameters];
	[mDict setObject:[self jwtDate:0] forKey:@"iat"];
	[mDict setObject:[self jwtDate:60] forKey:@"exp"];
	
	// NSLog(@"%@ 参数 = %@", name, mDict);
	
	//    NSLog(@"%@", [GetUserDefaule(Token) valueForKey:@"access_token"]);
	//    if ([GetUserDefaule(Token) valueForKey:@"access_token"] == NULL) {
	//        NSLog(@"wu");
	//        sleep(1);
	//    }
	//    else
	//        NSLog(@"xxxxx");
	
	// 请求头
	[self.requestSerializer setValue:[GetUserDefaule(Token) valueForKey:@"access_token"] forHTTPHeaderField:@"Authorization"];
	//    NSLog(@"--------token = %@", GetUserDefaule(Token));
	// 移除请求回来的responseObjective的空类型（针对性使用）
	AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
	response.removesKeysWithNullValues = YES;
	self.responseSerializer = response;
	
	// JWT秘钥
	NSString *secret = JWTSecret;
	id<JWTAlgorithm> algorithm = [JWTAlgorithmFactory algorithmByName:@"HS256"];
	JWTBuilder *jwtBuilder = [JWTBuilder encodePayload:mDict].secret(secret).algorithm(algorithm);
	NSString *jwtStr = [NSString stringWithFormat:@"%@", jwtBuilder.encode];
	
	//    NSLog(@"jwt = %@", jwtStr);
	
	
	// path ，body ， query 无论哪种都加上“jwt=%@”
	
	if ([method isEqualToString:@"GET"]) {
		NSString *url = [NSString stringWithFormat:@"%@?jwt=%@", URLString, jwtStr];
		[self GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
			id obj = [self netSuccess:responseObject];
			NSLog(@"%@ success = %@", name, obj);
			callBack(obj);
		} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
			NSLog(@"报错的接口是%@", URLString);
			[self netFailure:error];
			failCallBack(error);
		}];
	}
	
	
	else if ([method isEqualToString:@"POST"]) {
		[self POST:URLString parameters:@{@"jwt":jwtStr} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
			id obj = [self netSuccess:responseObject];
			NSLog(@"%@ success = %@", name, obj);
			callBack(obj);
		} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
			NSLog(@"%@", error);
			NSLog(@"报错的接口是%@", URLString);
			[self netFailure:error];
			failCallBack(error);
		}];
	}
	
	else if ([method isEqualToString:@"PUT"]) {
		[self PUT:URLString parameters:@{@"jwt":jwtStr} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
			id obj = [self netSuccess:responseObject];
			NSLog(@"%@ success = %@", name, obj);
			callBack(obj);
		} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
			NSLog(@"%@", error);
			NSLog(@"报错的接口是%@", URLString);
			[self netFailure:error];
			failCallBack(error);
		}];
	}
	
	else if ([method isEqualToString:@"DELETE"]) {
		[self DELETE:URLString parameters:@{@"jwt":jwtStr} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
			id obj = [self netSuccess:responseObject];
			NSLog(@"%@ success = %@", name, obj);
			callBack(obj);
		} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
			NSLog(@"报错的接口是%@", URLString);
			[self netFailure:error];
			failCallBack(error);
		}];
	}
	
}

// 成功回调
- (id)netSuccess:(id)responseObject {
	if (![_currVC isKindOfClass:[LoginPhoneViewController class]]) {
		[MBProgressHUD hideHUDForView:_currVC.view animated:YES];
	}
    id obj = [JWT decodeMessage:responseObject[@"token"]].secret(JWTSecret).algorithmName(@"HS256").decode;
    return [obj valueForKey:@"payload"];
}
// 失败回调
- (void)netFailure:(id)error {
    [MBProgressHUD hideHUDForView:_currVC.view animated:YES];
	NSLog(@"111111111111111111111111111111111111111111");
	
	//如果后台返回的错误不是JSON（比如极光推送的一些错误后台不可控），直接拦截掉，不让他弹窗
	NSData *errorData = ((NSError *)error).userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
	if (!errorData) {
		return;
	}
	/*
	if ([_currVC isKindOfClass:[HomeViewController class]]) {
		return;
	}
	 */
    [_currVC presentViewController:[self AFNErrorAlert:error] animated:YES completion:nil];
}

- (UIAlertController *)AFNErrorAlert:(NSError *)error {
    
    NSString *message;
    
    if (error.code == -1009 || error.code == -1001 || error.code == -1005 || error.code == -1003) {
        message = @"请检查网络状况";
    }
    else {
        NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
		
		if (errorData) {
			NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: errorData options:kNilOptions error:nil];
			NSLog(@"error--%@", serializedData);
			message = serializedData[@"message"];
		}
		else {
			NSLog(@"error--%@", error);
			message = @"未知错误，请重新尝试";
		}
		
    }
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        if ([message isEqualToString:@"请先登录"]) {
            AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
            LoginViewController *loginVC = [[LoginViewController alloc] init];
            UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginVC];
            appDelegate.window.rootViewController = nav;
        }
		if ([message containsString:@"面试服务费不足"] || [message containsString:@"保证金不足"]) {
			//以下3种都是用present打开的，进行dismiss，其余pop
			if ([_currVC isKindOfClass:[AddJobViewController class]]||
				[_currVC isKindOfClass:[AddResumeViewController class]]||
				[_currVC isKindOfClass:[WebViewController class]]) {
				[_currVC dismissViewControllerAnimated:YES completion:nil];
			}
			else {
				[_currVC.navigationController popViewControllerAnimated:YES];
			}
		}
    }]];
    
    return alert;
}


// jwt 时间样式
- (NSString *)jwtDate:(int)time {
    return [NSString stringWithFormat:@"%ld", (long)[[NSDate dateWithTimeIntervalSinceNow:time] timeIntervalSince1970]];
}

/** 2018.11.02 新增以下方法，封装By Oldfish */
//上传视频到服务器
- (void)uploadVideoForPath:(NSURL *)videoPath
				  callBack:(void(^)(id responseObject))callBack {
	
	_currVC = [[[UIView alloc] init] topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
	
	//一般来说从选取完视频那一刻起就需要小菊花了，而不是到上传服务器的时候，因而在具体类中具体添加，此处先注释掉
	//[MBProgressHUD showHUDAddedTo:_currVC.view animated:YES];
	
	AFHTTPSessionManager *afn = [AFHTTPSessionManager manager];
	
	// 请求头
	[afn.requestSerializer setValue:[GetUserDefaule(Token) valueForKey:@"access_token"]forHTTPHeaderField:@"Authorization"];
	
	NSLog(@"videoPath is %@", videoPath);
	NSDictionary *dict = @{
						   @"video":@""
						   };
	[afn POST:APIMicrovideos parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
		
		NSData *videoData = [NSData dataWithContentsOfURL:videoPath];
		
		[formData appendPartWithFileData:videoData
									name:@"video"
								fileName:[videoPath lastPathComponent]
								mimeType:@"video"];
		NSLog(@"video data is %@", formData);
		// 工程里的视频
		//[formData appendPartWithFileURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:videoPath ofType:nil]] name:@"file" fileName:@"video" mimeType:@"video/mp4" error:nil];
		
	} progress:nil
	  success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
		  
		  [MBProgressHUD hideHUDForView:_currVC.view animated:YES];
		  id obj = [JWT decodeMessage:responseObject[@"token"]].secret(JWTSecret).algorithmName(@"HS256").decode;
		  NSString *path = [[[obj valueForKey:@"payload"] valueForKey:@"data"] valueForKey:@"video"];
		  NSLog(@"上传视频 success = %@", path);
		  callBack([obj valueForKey:@"payload"]);
		  
	  } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
		  NSLog(@"上传视频 failure = %@", error);
		  [MBProgressHUD hideHUDForView:_currVC.view animated:YES];
		  [_currVC presentViewController:[LZCTools AFNErrorAlert:error] animated:YES completion:nil];
		  
	  }];
}

//上传图片
- (void)uploadImage:(UIImage *)img
		   callBack:(void(^)(id responseObject))callBack {
	
	_currVC = [[[UIView alloc] init] topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
	[MBProgressHUD showHUDAddedTo:_currVC.view animated:YES];
	
	AFHTTPSessionManager *afn = [AFHTTPSessionManager manager];
	
	// 请求头
	[afn.requestSerializer setValue:[GetUserDefaule(Token) valueForKey:@"access_token"]forHTTPHeaderField:@"Authorization"];
	NSDictionary *dict = @{
						   @"file[]":@[]
						   };
	
	[afn POST:APIImages parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
		// formData: 专门用于拼接需要上传的数据,在此位置生成一个要上传的数据体
		// 这里的_photoArr是你存放图片的数组
		NSData *imageData = UIImageJPEGRepresentation(img, 0.8);
		
		// 在网络开发中，上传文件时，是文件不允许被覆盖，文件重名
		// 要解决此问题，
		// 可以在上传时使用当前的系统事件作为文件名
		NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
		// 设置时间格式
		[formatter setDateFormat:@"yyyyMMddHHmmss"];
		NSString *dateString = [formatter stringFromDate:[NSDate date]];
		NSString *fileName = [NSString  stringWithFormat:@"%@.jpg", dateString];
		/*
		 *该方法的参数
		 1. appendPartWithFileData：要上传的照片[二进制流]
		 2. name：对应网站上[upload.php中]处理文件的字段（比如upload）
		 3. fileName：要保存在服务器上的文件名
		 4. mimeType：上传的文件的类型
		 */
		[formData appendPartWithFileData:imageData name:@"pic[]" fileName:fileName mimeType:@"image/jpeg"]; //
		NSLog(@"image data is %@", formData);
		
	} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
		id obj = [JWT decodeMessage:responseObject[@"token"]].secret(JWTSecret).algorithmName(@"HS256").decode;
		//        return [obj valueForKey:@"payload"];
		NSArray *imgArr = [[[obj valueForKey:@"payload"] valueForKey:@"data"] valueForKey:@"images"];
		NSLog(@"上传图片 success = %@", imgArr);
		[MBProgressHUD hideHUDForView:_currVC.view animated:YES];
		callBack([obj valueForKey:@"payload"]);
		
	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
		NSLog(@"上传图片 failure = %@", error);
		[_currVC presentViewController:[LZCTools AFNErrorAlert:error] animated:YES completion:nil];
		[MBProgressHUD hideHUDForView:_currVC.view animated:YES];
	}];
}

@end
